﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace eStore.Models
{
    public partial class ShoppingCart
    {
        public string ShoppingCartId { get; set; }
        public const string CartSessionKey = "CartId";
        public const string CartRecordKey = "RecordId";

        private ICartRepository _cartRepo = null;
        private IUserRepository _userRepo = null;

        private Cart _currentCart = null;
        private static ShoppingCart _shoppingcartInstance = null;

        public ShoppingCart():this(new CartRepository(),new UserRepository()){ 
        
        }

        public ShoppingCart(ICartRepository cartRepo,IUserRepository userRepo) {
            _cartRepo = cartRepo;
            _userRepo = userRepo;
        }

        public Cart CurrentCart { 
                get {
                    return _currentCart;
                }
                set {
                    _currentCart = value;
                }
        }

        public static ShoppingCart GetCart(HttpContextBase context, bool bRelease)
        {
            if (_shoppingcartInstance == null || bRelease)
            {
                _shoppingcartInstance = new ShoppingCart();
                _shoppingcartInstance.ShoppingCartId = _shoppingcartInstance.GetSessionId(context);
                _shoppingcartInstance.InitializeCart(context);
            }

            if (_shoppingcartInstance != null && _shoppingcartInstance.CurrentCart == null)
                _shoppingcartInstance.InitializeCart(context);
            return _shoppingcartInstance;
        }

        // We're using HttpContextBase to allow access to cookies.
        public String GetSessionId(HttpContextBase context)
        {
            if (context.Session[CartSessionKey] == null)
            {
                if (!string.IsNullOrWhiteSpace(context.User.Identity.Name))
                {
                    // User is logged in, associate the cart with there username
                    context.Session[CartSessionKey] = context.User.Identity.Name;
                }
                else
                {
                    // Generate a new random GUID using System.Guid Class
                    Guid tempCartId = Guid.NewGuid();

                    // Send tempCartId back to client as a cookie
                    context.Session[CartSessionKey] = tempCartId.ToString();
                }
            }
            return context.Session[CartSessionKey].ToString();
        }

        // We're using HttpContextBase to allow access to cookies.
        public String GetCartRecordId(HttpContextBase context)
        {
            if (context == null)
                return CurrentCart.RecordId.ToString();

            if (context.Session[CartRecordKey] == null)
            {
                context.Session[CartRecordKey] = CurrentCart!=null?CurrentCart.RecordId:0;
            }
            return context.Session[CartRecordKey].ToString();
        }


        public void InitializeCart(HttpContextBase context)
        {
            try
            {
                //to check if last used cart
                string sLastRecordId = this.GetCartRecordId(context) != null ? this.GetCartRecordId(context).ToString() : "0";
                if (!(String.IsNullOrWhiteSpace(sLastRecordId)))
                {
                    _currentCart = _cartRepo.GetCartByRecordId(sLastRecordId);
                    if(_currentCart!=null)
                        this.ShoppingCartId = _currentCart.SessionId.ToString();
                }

                if (_currentCart == null)
                {
                    
                    Cart oNewCart = new Cart();
                    oNewCart.SessionId = this.ShoppingCartId;
                    oNewCart.CreatedDate = DateTime.Now;
                    oNewCart.CartQty = 0;
                    _cartRepo.SubmitCart(oNewCart);
                    _currentCart = oNewCart;
                }
            }
            catch (Exception)
            {
                
                throw;
            }

        }

        public Cart AddItem(Product oItem)
        {
            var cart= _cartRepo.AddProduct(this._currentCart, oItem);
            return cart;
        }

        public Cart MigrateCart(string sUserName)
        {
            Cart currentCart = _cartRepo.GetCartByRecordId(this.GetCartRecordId(null));
            if (currentCart != null)
            {
                _cartRepo.MigrateCart(currentCart, sUserName);
                this.ShoppingCartId = sUserName;
            }
            return currentCart;
        }

        public int TotalCartItemsCount() {
            int iCounter = 0;
            if (CurrentCart != null)
                iCounter =_cartRepo.GetCartItemsCount(CurrentCart);
            return iCounter ;
        }

        public List<CartItem> GetAllCartItems() {

            if (CurrentCart != null)
                return _cartRepo.GetCartItems(CurrentCart);
             return null;
        }

        public Order CreateOrder(CheckOutModel oModel) {

            Order oNewOrder = null;
            String sName = this.CurrentCart.SessionId;
            User user  = null;
            if (_userRepo != null)
            {
                user = _userRepo.GetUserByName(sName);
            }

            if (_cartRepo != null && user!=null)
            {
                oNewOrder = _cartRepo.CreateOrder(oModel, this.CurrentCart, user.UserId);
            }
            
            return oNewOrder;
        }
    }
}